package com.huayi.datagovernance.utils.date;

import cn.hutool.core.date.*;
import cn.hutool.core.lang.Console;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.Calendar;
import java.util.Date;

/**
 * 日期时间工具-DateUtil 接口示例
 * api： https://apidoc.gitee.com/dromara/hutool/
 * @author wuch
 * @version 1.0
 * @date 2021/4/12 18:07
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class DateTimeDemo {
    /**
     * DateTime类继承于java.util.Date类，为Date类扩展了众多简便方法，
     * 这些方法多是DateUtil静态方法的对象表现形式，使用DateTime对象可以完全替代开发中Date对象的使用。
     */


    /**
     * 新建对象，获取当前时间
     * DateTime对象包含众多的构造方法，构造方法支持的参数有：
     *
     * Date
     * Calendar
     * String(日期字符串，第二个参数是日期格式)
     * long 毫秒数
     * 构建对象有两种方式：DateTime.of()和new DateTime()：
     */
    @Test
    public void demo1(){
        Date date = new Date();

        //new方式创建
        DateTime time = new DateTime(date);
        Console.log(time);
        DateTime time1 = new DateTime();
        Console.log(time1);

        //of方式创建
        DateTime now = DateTime.now();
        Console.log(now);
//        System.out.println(Console.lineNumber());//打印行号
        DateTime dt = DateTime.of(date);
        Console.log(dt);
    }

    /**
     * 使用对象
     *
     * DateTime的成员方法与DateUtil中的静态方法所对应，因为是成员方法，因此可以使用更少的参数操作日期时间。
     * 示例：获取日期成员（年、月、日、时、分、秒等）
     */
    @Test
    public void demo2(){
        //根据指定格式，获取当前时间
        DateTime dateTime = new DateTime("2021-04-13 10:22:38", DatePattern.NORM_DATETIME_FORMAT);

        //年，结果：2021
        int year = dateTime.year();
        Console.log("年： "+year);
        Console.log("年： "+dateTime.getField(Calendar.YEAR));

        //月份，结果：Month.APRIL 4 ，月份是从0开始，必须加1
        Month month = dateTime.monthEnum();
        Console.log("月： "+month);
        Console.log("月： "+dateTime.monthStartFromOne());//获取月份值，从1开始算

        //日，结果：13
        int day = dateTime.dayOfMonth();
        Console.log("日： "+day);

        //时，结果：10
        int hour = dateTime.hour(true);
        Console.log("时： "+hour);

        //分，结果：22
        int minute = dateTime.minute();
        Console.log("分： "+minute);

        //秒，结果：38
        int second = dateTime.second();
        Console.log("秒： "+second);
    }

    /**
     *  日期常用判断、计算
     */
    @Test
    public void demo3() {
        DateTime dateTime1 = new DateTime("2021-02-14 10:00:00", DatePattern.NORM_DATETIME_FORMAT);
        DateTime dateTime2 = new DateTime("2021-04-13 10:22:38", DatePattern.NORM_DATETIME_FORMAT);
        //计算相差时长
        DateBetween between = dateTime1.between(dateTime2);
        Console.log(between);//59天22分38秒
        Console.log(between.betweenMonth(false));//相差月份  true:忽略天数差  2  false:如果起始日期的天大于结束日期的天，月数要少算1 1

        //获得指定日期是这个日期所在月份的第几天，从1开始
        Console.log(dateTime2.dayOfMonth());//13
        //获得指定日期是星期几，1表示周日，2表示周一
        Console.log(dateTime2.dayOfWeek());//3 周二
        //获得天所在的周是这个月的第几周
        Console.log(dateTime2.dayOfWeekInMonth());
    }

    /**
     * 调整日期和时间
     *
     * DateTime对象默认是可变对象（调用offset、setField、setTime方法默认变更自身），
     * 但是这种可变性有时候会引起很多问题（例如多个地方共用DateTime对象）。
     * 我们可以调用setMutable(false)方法使其变为不可变对象。
     * 在不可变模式下，offset、setField方法返回一个新对象，setTime方法抛出异常。
     */
    @Test
    public void demo4(){
        DateTime dateTime1 = new DateTime("2017-01-05 12:34:23", DatePattern.NORM_DATETIME_FORMAT);
        //默认情况下DateTime为可变对象，此时offset == dateTime
        // DateField.YEAR:偏移字段  offset:偏移量，正数为向后偏移，负数为向前偏移
        DateTime offset = dateTime1.offset(DateField.YEAR, 2);
        Console.log("可变："+offset+" | "+ dateTime1);

        DateTime dateTime2 = new DateTime("2017-01-05 12:34:23", DatePattern.NORM_DATETIME_FORMAT);
        //设置为不可变对象后变动将返回新对象，此时offset != dateTime
//        dateTime.setMutable(false);//设置不可变 等于 offsetNew
        offset = dateTime2.offsetNew(DateField.HOUR, -2);
        Console.log("不可变可变："+offset+" | "+ dateTime2);
    }
}
